/**
 * 
 */
package org.nielin.bestwaper.core;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author rockydai
 *
 */
public abstract class WebEntity {	
	protected String id;
    protected List<Validator> validator;
	
	public String getId() {
		return id;
	}
	
	public abstract void go( WebEntityContext context );
    
    /**
     * 检查参数合法性
     * @return true 合法 false 不合法
     */
    public boolean validate( WebEntityContext context ) {
        String profileMsg = "WebEntity.validate, id[" + getId() + "]";
        UtilTimerStack.push(profileMsg);
        try {
            HttpServletRequest request = context.getRequest();
            HttpServletResponse response = context.getResponse();
            
            // 原子操作检查，在这里检查可以全面检查到所有的请求，包括View、Controller、Controller后的结果
            AtomicAction atomicAction = (AtomicAction)request.getAttribute( "atomicAction" );
            if ( atomicAction != null && !atomicAction.canDo( id ) ) {
                atomicAction.reDo(request, response);
            }
            
            List<Validator> validators = ValidatorMap.getInstance().getValidatorList(id);
            Map<String,Object> validatorContext = new HashMap<String,Object>();
            validatorContext.put( "request", request );
            validatorContext.put( "response", response );
            Map<String, String> validatedParams = new HashMap<String,String>();
            if ( validators != null )
            {
                for( Validator validator : validators )
                {
                    MyLogger.getNormal().debug("validator:" + validator.getValidatorType() );
                    validator.setValidatorContext(validatorContext);
                    try {
                        if ( !validator.validate( request ) )
                        {
                            MyLogger.getNormal().warn("request to id[" + id + "] params[" + request.getParameterMap() + "] validate fail!");
                            return false;
                        }
                        if ( validator instanceof FieldValidator && validator instanceof FieldValidatorSupport )
                        {
                            FieldValidator fieldValidator = (FieldValidator)validator;
                            FieldValidatorSupport fieldValidatorSupport = (FieldValidatorSupport)validator;
                            String paramName = fieldValidator.getFieldName();
                            String paramValue = (String)fieldValidatorSupport.getFieldValue( paramName, request );
                            validatedParams.put( paramName, paramValue );
                        }
                    } catch (ValidationException e) {
                        MyLogger.getNormal().error( "validator[" + validator.getValidatorType() + "] validate fail ", e );
                    }
                }
            }
            
            context.setValidatedParams(validatedParams);
            return true;
        }
        finally {
            UtilTimerStack.pop(profileMsg);
        }
    }
    
    public static void go( ServletRequest request, ServletResponse response, 
            String id, Map<String,String> params ) {
        
        String url = "/g?";
        String sid = (String)request.getAttribute( "sid" );
        if ( sid != null && sid.length() >= 4 )
        {
            url += ( "s=" + sid );
        }
        url += ("&id=" + id);
        if ( params != null ) {
            Set<String> paramNames = params.keySet();
            for( String paramName : paramNames ) {
                if ( !paramName.equals("s") && !paramName.equals("id") )
                {
                    url += ("&" + paramName + "=" + params.get(paramName) );            
                }
            }            
        }
        
        MyLogger.getNormal().debug( "get to url [" + url + "]" );
        
        try
        {
            javax.servlet.RequestDispatcher dispatcher = request.getRequestDispatcher(url);          
            dispatcher.forward(request, response);
        }
        catch(Exception e)
        {
            MyLogger.getNormal().error( "dispatch to url[" + url + "fail, exception:", e );
        }        
    }
}
